home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
MacHack 1997
/
MacHack 1997.toast
/
Hacks
/
Hacks ’96
/
troz.cgi
/
MyCGIProcess.c
next >
Wrap
Text File
|
1996-06-22
|
12KB
|
434 lines
/*****
*
* Troz CGI
*
* MyCGIProcess.c
*
*
*
* by Grant Neufeld
*
* Copyright ©1996 by Grant Neufeld
*
* http://arpp.carleton.ca/grant/
* gneufeld@ccs.carleton.ca
* grant@acm.org
*
*****/
#include "MyConfiguration.h"
#if kCompileWithCGICode
#include <string.h>
#include <Threads.h>
#include <QCAPI.h>
#include "globals.h"
#include "CGI.h"
#include "CustomHandlers.h"
#include "DebugUtil.h"
#include "LogUtil.h"
#include "MemoryUtil.h"
#include "ProcessUtil.h"
#include "otherprocs.h"
/*** LOCAL CONSTANTS ***/
#define krtTrozType 'troZ'
#define krsTrozHTTPHeader 10101
#define krsTrozHTMLFirstChunk 10102
#define krsTrozHTMLSecondChunk 10103
#define krsTrozPinkyHTML 10110
#define krsTrozQuickCamHTML 10111
/*** LOCAL VARIABLES ***/
Handle vTrozHTTPHeader;
Handle vTrozHTMLFirstChunk;
Handle vTrozHTMLSecondChunk;
int vTrozHTTPHeaderSize;
int vTrozHTMLFirstChunkSize;
int vTrozHTMLSecondChunkSize;
Handle vTrozPinkyHTML;
int vTrozPinkyHTMLSize;
Handle vTrozQuickCamHTML;
int vTrozQuickCamHTMLSize;
UInt16 vTrozRandomRate;
FSSpec vTrozQuickCamFile;
/*** LOCAL FUNCTIONS ***/
Boolean TrozShouldWeNarf ( CGIHdl );
OSErr TrozUseQuickCam ( CGIHdl );
/*** CUSTOM CGI FUNCTION ***/
/* This function is where the CGI is actually processed.
You should replace its contents with your own.
You need to allocate (*theCGIHdl)->responseData using MemoryNewHandle.
Put an HTTP header at the beginning of (*theCGIHdl)->responseData.
Put your data immediately following the last character of the HTTP header.
(*theCGIHdl)->responseData will be automatically deallocated by the CGI handler.
You should set (*theCGIHdl)->responseSize to be the size of the responseData,
including null terminator if you have one. */
void
CustomCGIProcess ( CGIHdl theCGIHdl )
{
Boolean processEvent;
Handle returnData;
// short returnDataSize;
OSErr theErr;
// char * theOriginalURL;
// short theOriginalURLSize;
// short scriptNameSize;
// short serverNameSize;
SInt8 savedHandleState;
// long returnDataPostion;
// short extraBytesForHandle;
/* debugging check to ensure that theCGIHdl is not NULL */
my_assert ( theCGIHdl != NULL,
"\pCustomCGIProcess: theCGIHdl is NULL" );
//••• need to test to ensure that the needed CGIHdl fields are present
/* Test to see if the event should be processed */
processEvent = TrozShouldWeNarf ( theCGIHdl );
if ( processEvent )
{
/* the event met the test requirements, so process it */
if ( Random() % 2 )
{
/* at random, use the QuickCam instead */
theErr = TrozUseQuickCam ( theCGIHdl );
if ( theErr == noErr )
{
returnData = CGINewHandle ( theCGIHdl, vTrozQuickCamHTMLSize + 1, &theErr );
if ( returnData != NULL )
{
savedHandleState = HGetState ( returnData );
HLock ( returnData );
strcpy ( *returnData, *vTrozQuickCamHTML );
QCBlockBoundsCheckNow ();
HSetState ( returnData, savedHandleState );
(*theCGIHdl)->responseSize = vTrozQuickCamHTMLSize + 1;
(*theCGIHdl)->responseData = returnData;
}
}
}
else
{
theErr = 1;
}
if ( theErr != noErr )
{
/* determine the size of the intended url string */
// savedHandleState = HGetState ( (Handle)theCGIHdl );
// HLock ( (Handle)theCGIHdl);
// scriptNameSize = strlen ( (char *)(*theCGIHdl)->script_name );
// serverNameSize = strlen ( (char *)(*theCGIHdl)->server_name );
// HSetState ( (Handle)theCGIHdl, savedHandleState );
// returnDataSize = vTrozHTTPHeaderSize + serverNameSize + scriptNameSize +
// vTrozHTMLFirstChunkSize + scriptNameSize + vTrozHTMLSecondChunkSize;
returnData = CGINewHandle ( theCGIHdl, vTrozPinkyHTMLSize + 1, &theErr );
// returnData = CGINewHandle ( theCGIHdl, returnDataSize + 1, &theErr );
if ( returnData != NULL )
{
savedHandleState = HGetState ( returnData );
HLock ( returnData );
strcpy ( *returnData, *vTrozPinkyHTML );
QCBlockBoundsCheckNow ();
#if 0
returnDataPostion = nil;
/* write out the http header */
strcpy ( *returnData, *vTrozHTTPHeader );
QCBlockBoundsCheckNow ();
returnDataPostion += vTrozHTTPHeaderSize;
/* write out the server name */
strcpy ( *returnData + returnDataPostion, (*theCGIHdl)->server_name );
QCBlockBoundsCheckNow ();
returnDataPostion += serverNameSize;
/* write out the script name */
strcpy ( *returnData + returnDataPostion, (*theCGIHdl)->script_name );
QCBlockBoundsCheckNow ();
returnDataPostion += scriptNameSize;
/* write out the first html chunk */
strcpy ( *returnData + returnDataPostion, *vTrozHTMLFirstChunk );
QCBlockBoundsCheckNow ();
returnDataPostion += vTrozHTMLFirstChunkSize;
/* write out the Original URL, in relative form */
strcpy ( *returnData + returnDataPostion, (*theCGIHdl)->script_name );
QCBlockBoundsCheckNow ();
returnDataPostion += scriptNameSize;
/* write out the second (and last) html chunk */
strcpy ( *returnData + returnDataPostion, *vTrozHTMLSecondChunk );
QCBlockBoundsCheckNow ();
#endif
/* null terminate the text */
// (*returnData)[returnDataSize] = nil;
// QCBlockBoundsCheckNow ();
HSetState ( returnData, savedHandleState );
(*theCGIHdl)->responseSize = vTrozPinkyHTMLSize + 1;
(*theCGIHdl)->responseData = returnData;
/* you should try to make use of giving time,
especially in for and while loops or where you have to wait for
some other process to return data or finish a task. */
// ProcessGiveTime ( nil );
}
}
}
} /* CustomCGIProcess */
/* This is where we determine whether to interrupt the user's access with
a Pinky troZ! attack */
Boolean
TrozShouldWeNarf ( CGIHdl theCGIHdl )
{
Boolean weShouldNarf;
short scriptNameLength;
long stringDiff;
SInt16 randomValue;
weShouldNarf = false;
//••• should deal appropriately with absent CGIHdl fields - IE. default to true for them
if ( ((*theCGIHdl)->method == HTTP_get) || ((*theCGIHdl)->method == HTTP_conditionalGet) )
{
/* test if action is preprocessor or ACTION */
// •••
// if ( • )
// {
scriptNameLength = strlen ( (*theCGIHdl)->script_name );
/* test if last charcter of script_name is '/' */
if ( ((*theCGIHdl)->script_name)[scriptNameLength - 1] == '/' )
{
stringDiff = nil;
}
else if ( scriptNameLength > 6 )
{
/* test if script_name ends in ".html" */
stringDiff = strcmp ( ".html", (*theCGIHdl)->script_name + scriptNameLength - 5 );
}
if ( stringDiff == nil )
{
/* get a random to choose whether to narf */
randomValue = Random() % vTrozRandomRate;
if ( randomValue == nil )
{
weShouldNarf = true;
}
}
// }
}
return weShouldNarf;
} /* TrozShouldWeNarf */
OSErr
TrozUseQuickCam ( CGIHdl theCGIHdl )
{
OSErr theErr;
theErr = SaveJPEGFromQuickCam ( vTrozQuickCamFile, 32 );
return theErr;
}
/* this function will be called after the cgi result has been returned.
It will contain the same CGIHdl that was used for the CustomCGIProcess.
This function's prototype is defined in "CGI.h" */
void
CustomCGIPostProcess ( CGIHdl theCGIHdl )
{
} /* CustomCGIPostProcess */
/*** CUSTOM CGI INITIALIZATION ***/
#pragma segment Startup
/* Put any of the initialization you need done, here.
This function will be called once: in-between the startup
sequence and the main event loop.
Return true if the initialization was successful, otherwise false.
An initialization failure will result in the application quitting. */
Boolean
CustomCGIStartup ( void )
{
OSErr theErr;
SInt8 savedHandleState;
Str255 theFileName;
/* get the FSSpec for the file to store the JPEG quickcam grab in */
GetIndString ( theFileName, 10001, 3 );
theErr = FSMakeFSSpec ( gProcessFSSpec.vRefNum, gProcessFSSpec.parID, theFileName, &vTrozQuickCamFile );
/* Load in the default blocks of text to return */
/* the pinky html */
vTrozPinkyHTML = Get1Resource ( krtTrozType, krsTrozPinkyHTML );
if ( vTrozPinkyHTML == NULL )
{
return false;
}
savedHandleState = HGetState ( vTrozPinkyHTML );
HLock ( vTrozPinkyHTML );
vTrozPinkyHTMLSize = strlen ( (char *)(*vTrozPinkyHTML) );
HSetState ( vTrozPinkyHTML, savedHandleState );
/* the QuickCam html */
vTrozQuickCamHTML = Get1Resource ( krtTrozType, krsTrozQuickCamHTML );
if ( vTrozQuickCamHTML == NULL )
{
return false;
}
savedHandleState = HGetState ( vTrozQuickCamHTML );
HLock ( vTrozQuickCamHTML );
vTrozQuickCamHTMLSize = strlen ( (char *)(*vTrozQuickCamHTML) );
HSetState ( vTrozQuickCamHTML, savedHandleState );
/* the HTTP Header */
vTrozHTTPHeader = Get1Resource ( krtTrozType, krsTrozHTTPHeader );
if ( vTrozHTTPHeader == NULL )
{
return false;
}
savedHandleState = HGetState ( vTrozHTTPHeader );
HLock ( vTrozHTTPHeader );
vTrozHTTPHeaderSize = strlen ( (char *)(*vTrozHTTPHeader) );
HSetState ( vTrozHTTPHeader, savedHandleState );
/* the first HTML chunk */
vTrozHTMLFirstChunk = Get1Resource ( krtTrozType, krsTrozHTMLFirstChunk );
if ( vTrozHTMLFirstChunk == NULL )
{
return false;
}
savedHandleState = HGetState ( vTrozHTMLFirstChunk );
HLock ( vTrozHTMLFirstChunk );
vTrozHTMLFirstChunkSize = strlen ( (char *)(*vTrozHTMLFirstChunk) );
HSetState ( vTrozHTMLFirstChunk, savedHandleState );
/* the second HTML chunk */
vTrozHTMLSecondChunk = Get1Resource ( krtTrozType, krsTrozHTMLSecondChunk );
if ( vTrozHTMLSecondChunk == NULL )
{
return false;
}
savedHandleState = HGetState ( vTrozHTMLSecondChunk );
HLock ( vTrozHTMLSecondChunk );
vTrozHTMLSecondChunkSize = strlen ( (char *)(*vTrozHTMLSecondChunk) );
HSetState ( vTrozHTMLSecondChunk, savedHandleState );
vTrozRandomRate = 3;
GetDateTime ( (unsigned long *)(&(qd.randSeed)) );
return true;
} /* CustomCGIStartup */
/*** CUSTOM CGI CLEAN UP ***/
#pragma segment Main
/* This function is called at quitting time. Put any cleanup you need to do in it.
Return true if you are succeful.
Return false if you are unable to quit for some reason (this generally only
applies when the user cancels)
allowUserInteract specifies whether you can make user interface calls.
However, CGIs generally should not rely on any user interface calls, so don't
depend on them. */
Boolean
CustomCGIQuit ( Boolean allowUserInteract )
{
#pragma unused (allowUserInteract)
return true;
}/* CustomCGIQuit */
/*** WSAPI SUPPORT ***/
#if kCompilingForWSAPI
#define kFileCreatorTypeAny '* '
/* See the WSAPI documentation for further details on the use of
WSAPI_RegisterAction and WSAPI_RegisterSuffix. */
WSAPI_ErrorCode
CustomCGIWSAPIRegister ( WSAPI_CommandPBPtr commandPtr )
{
WSAPI_ErrorCode theErr;
/* return plug-in name and abilities, register actions and suffixes. */
/* your code must make at least one of the following WSAPI Register
calls or there's no way for WebSTAR to pass CGI requests to your plug-in */
/* in this example, we're registering "GRANTSCGI" as an action.
You should always use the kMyCGIName constant (don't forget to properly
set it in "MyConfiguration.h". */
theErr = WSAPI_RegisterAction ( commandPtr, "TROZCGI", kMyCGIName );
if ( theErr != WSAPI_I_NoErr )
{
/* PlugIn Action didn't register. Notify user.
May want to take some action other than just
displaying this message */
WSAPI_DisplayMessage ( commandPtr, "TROZCGI: Couldn't register the action." );
}
/* in this example, we're registering ".TROZC" as a suffix mapping for
the "GRANTSCGI" action (registered above). We're also registering it
for files that have the TEXT filetype and CGI? as their creator type.
If you don't care about particular file or creator types, then just
use '* ' (defined as kFileCreatorTypeAny directly above this function). */
theErr = WSAPI_RegisterSuffix ( commandPtr, "TROZCGI", ".TROZ",
'TEXT', 'troZ', "text/html") );
if ( theErr != WSAPI_I_NoErr )
{
/* PlugIn Suffix didn't register. Notify user.
May want to take some action other than just
displaying this message */
WSAPI_DisplayMessage ( commandPtr, "TROZCGI: Couldn't register the suffix." );
}
return theErr;
} /* CustomCGIWSAPIRegister */
#endif /* kCompilingForWSAPI */
#endif /* kCompileWithCGICode */
/*** EOF ***/